package com.yict.common.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.thoughtworks.xstream.XStream;
import com.yict.common.Constants;

/**
 * <h3>字符串处理类</h3> <h4>Description</h4>
 * 
 * <h4>Special Notes</h4>
 * 
 * 
 * @ver 0.5
 * @author Jay Wu 2009年11月3日
 */
public class StringUtil extends StringUtils {

	private static final Log logger = LogFactory.getLog(StringUtil.class);

	/**
	 * 
	 * @return 随机字符
	 * 
	 * @author Solex.Li
	 */
	public static String random(int count) {
		return RandomStringUtils.randomAlphanumeric(count);
	}

	/**
	 * 替换s到e的字符串
	 * 
	 * @param s
	 *            开始字符
	 * @param e
	 *            结束字符
	 * @param content
	 *            要截取的字符
	 * @param value
	 *            替换内容
	 * @return
	 */
	public static String replaceInValue(String s, String e, String content, String value) {
		if (content == null)
			return null;
		int i = 0;
		int k = 0;
		if ((i = (content.indexOf(s, i))) >= 0 && (k = (content.indexOf(e, k))) >= 0) {
			StringBuffer sbf = new StringBuffer();
			int s_length = s.length();
			int e_length = e.length();
			sbf.append(content.substring(0, i)).append(value);
			int n = i + s_length;
			int m = k + e_length;
			for (; ((i = (content.indexOf(s, n))) >= 0 && (k = (content.indexOf(e, m))) >= 0);) {
				sbf.append(content.substring(m, i)).append(value);
				n = i + s_length;
				m = k + e_length;
			}
			sbf.append(content.substring(m, content.length()));
			return sbf.toString();
		}
		return content;
	}

	/**
	 * 截取字符串前面一顶长度的字符
	 * 
	 * @param length
	 *            要截取长度
	 * @param content
	 *            内容
	 * @return
	 */
	public static String cutString(int length, String content) {
		if (content.length() > length)
			return content.substring(0, length);
		return content;
	}

	/**
	 * 截取字符串前面一顶长度的字符,同时增加"..."结尾 commons
	 * com.loyoyo.common.utils.StringUtil.java
	 * 
	 * @param length
	 * @param content
	 * @return String
	 * @author: bobo 2008-8-22 下午04:12:12
	 */
	public static String cutSubString(int length, String content) {
		if (content.length() > length)
			return content.substring(0, length) + "...";
		return content;
	}

	/**
	 * 解码
	 * 
	 * @param src
	 * @return
	 * @author Jay.Wu
	 */
	public static String unescape(String src) {
		StringBuffer tmp = new StringBuffer();
		tmp.ensureCapacity(src.length());
		int lastPos = 0, pos = 0;
		char ch;
		while (lastPos < src.length()) {
			pos = src.indexOf("%", lastPos);
			if (pos == lastPos) {
				if (src.charAt(pos + 1) == 'u') {
					ch = (char) Integer.parseInt(src.substring(pos + 2, pos + 6), 16);
					tmp.append(ch);
					lastPos = pos + 6;
				} else {
					ch = (char) Integer.parseInt(src.substring(pos + 1, pos + 3), 16);
					tmp.append(ch);
					lastPos = pos + 3;
				}
			} else {
				if (pos == -1) {
					tmp.append(src.substring(lastPos));
					lastPos = src.length();
				} else {
					tmp.append(src.substring(lastPos, pos));
					lastPos = pos;
				}
			}
		}
		return tmp.toString();
	}

	/**
	 * Add alias for each arguments in the SQL string
	 * 
	 * @param sqlString
	 * @return
	 * 
	 * @author Sagax.Luo
	 * @throws Exception
	 */
	public static String addAliasForSQLArgs(String sqlString, String[] aliases) throws Exception {
		String lowSqlString = sqlString.toLowerCase();

		if (lowSqlString.indexOf("select") == -1 || lowSqlString.indexOf("from") == -1)
			throw new Exception("非法SQL语句!!");

		String subArgsString = lowSqlString.substring(6, lowSqlString.indexOf("from"));
		String[] args = subArgsString.split(",");

		if (args.length != aliases.length)
			throw new Exception("Arguments的长度与Aliases的长度不匹配!!");

		StringBuffer argsWithAliases = new StringBuffer();
		for (int i = 0; i < args.length; i++) {
			args[i] = args[i] + " as " + aliases[i];

			argsWithAliases.append(args.length - 1 > i ? args[i] + ", " : args[i] + " ");
		}

		return sqlString.replaceFirst(subArgsString, argsWithAliases.toString());
	}

	/**
	 * 让普通的string支持类似EL标签的用法-简单版本 <br>
	 * <code>#contents#</code>
	 * 
	 * @param paraMap
	 * @param destStr
	 * @return
	 * @author Jay.Wu
	 */
	public static String replaceKeysSimple(Map<?, ?> paraMap, String destStr) {
		return replaceKeysByCrust(paraMap, destStr, "#");
	}

	/**
	 * 替换destStr里面有paraMap key的内容，替换成paraMap value
	 * 
	 * @param paraMap
	 *            替换的参考map
	 * @param destStr
	 *            目标字符串
	 * @param crust
	 *            匹配字符的外壳
	 * 
	 * @author Luvek.Lu
	 */
	public static String replaceKeysByCrust(Map<?, ?> paraMap, String destStr, String crust) {
		if (paraMap == null)
			return destStr;
		if (crust == null) {
			crust = "";
		}

		for (Iterator<?> iter = paraMap.keySet().iterator(); iter.hasNext();) {
			String key = (String) iter.next();
			String value = paraMap.get(key) == null ? "" : String.valueOf(paraMap.get(key));

			key = crust + key + crust;
			try {
				destStr = destStr.replace(key, value);
			} catch (Exception e) {
				logger.error(e);
			}
		}

		// log.debug(destStr);
		return destStr;
	}

	/**
	 * 加强版字符串判空：支持Object和字符串为null的对象
	 * 
	 * @param target
	 * @return
	 */
	public static boolean isNotBlankPlus(Object target) {
		if (target == null)
			return false;

		String targetStr = (String) target;

		if (isBlank(targetStr))
			return false;

		return !targetStr.equals("null");
	}

	/**
	 * 转义函数
	 * 
	 * @param rules
	 * @param target
	 * @author Jay Wu
	 * @return
	 */
	public static String transferRegex(String rules, String target) {
		if (StringUtil.isBlank(rules) || StringUtil.isBlank(target))
			return target;

		String[] objs = rules.split(",");
		for (int i = 0; i < objs.length; i++) {
			String rule = objs[i].trim();
			target = target.replace(rule, "\\" + rule);
		}

		return target;
	}

	/**
	 * 替换第一次出现的字符串
	 * 
	 * @param strSource
	 * @param strFrom
	 * @param strTo
	 * @author Jay Wu
	 * @return
	 */
	public static String replaceFirst(String strSource, String strFrom, String strTo) {
		// 如果要替换的子串为空，则直接返回源串
		if (strFrom == null || strFrom.equals(""))
			return strSource;

		String strDest = "";
		// 要替换的子串长度
		int intFromLen = strFrom.length();
		int intPos = strSource.indexOf(strFrom);

		// 获取匹配字符串的左边子串
		strDest = strDest + strSource.substring(0, intPos);
		// 加上替换后的子串
		strDest = strDest + strTo;
		// 获取匹配字符串的右边子串
		strSource = strSource.substring(intPos + intFromLen);

		// 左边+右边
		return strDest + strSource;
	}

	/**
	 * 计算出target在strSource中出现的次数
	 * 
	 * @param strSource
	 * @param target
	 * @author Jay.Wu
	 * @return
	 */
	public static int countString(String strSource, String target) {
		int result = 0;

		if (isBlank(strSource))
			return result;

		while (strSource.indexOf(target) != -1) {
			strSource = replaceFirst(strSource, target, "");
			result++;
		}

		return result;
	}

	/**
	 * 返回第times次target在strSource出现的次数
	 * 
	 * @param strSource
	 * @param target
	 * @param times
	 * @author Jay.Wu
	 * @return
	 */
	public static int indexOf(String strSource, String target, int times) {
		int result = -1;

		if (isBlank(strSource))
			return result;

		result = 0;
		int temp = 0;
		int count = 1;
		while ((temp = strSource.indexOf(target, temp) + 1) != -1) {
			if (times < count) {
				break;
			}

			if (result <= temp) {
				result = temp;
			} else {
				break;
			}

			count++;
		}

		return result - 1;
	}

	/**
	 * 返回第times次target在strSource出现的次数
	 * 
	 * @param strSource
	 * @param target
	 * @param times
	 * @author Jay.Wu
	 * @return
	 */
	public static int lastIndexOf(String strSource, String target, int times) {
		int result = -1;

		if (isBlank(strSource))
			return result;

		int temp = strSource.length() - 1;
		int count = 1;
		result = strSource.length();

		while ((temp = strSource.lastIndexOf(target, temp)) != -1) {
			if (times < count) {
				break;
			}

			if (result >= temp) {
				result = temp;
			} else {
				break;
			}

			temp--;

			count++;
		}

		if (result == strSource.length())
			return -1;

		return result;
	}

	/**
	 * 功能：验证字符串长度是否符合要求，一个汉字等于三个字符
	 * 
	 * @param strParameter
	 *            要验证的字符串
	 * @param limitLength
	 *            验证的长度
	 * @return 符合长度ture 超出范围false
	 */
	public static boolean validateStrByLength(String strParameter, int limitLength) {
		int temp_int = 0;
		byte[] b = strParameter.getBytes();

		for (int i = 0; i < b.length; i++) {
			if (b[i] >= 0) {
				temp_int = temp_int + 1;
			} else {
				temp_int = temp_int + 3;
				i++;
			}
		}

		if (temp_int > limitLength)
			return false;
		else
			return true;
	}

	/**
	 * 判断是否大小写字母
	 * 
	 * @param s
	 * @return
	 */
	public static boolean isLetter(String s) {
		for (int i = 0; i < s.length(); i++) {
			if (!((s.charAt(i) > 'a' && s.charAt(i) < 'z') || (s.charAt(i) > 'A' && s.charAt(i) < 'Z')))
				return false;
		}

		return true;
	}

	public static Object string2Object(String str, Class<?> classObj) {
		if (isEmpty(str))
			return null;

		if (classObj.equals(Date.class))
			return DateUtil.StringToDate(str, 2);

		return ClassUtil.newObjectByConstructor(classObj, new Class<?>[] { String.class },
				new Object[] { str });
	}

	public static Boolean toBoolean(Object object) {
		if (object == null)
			return null;

		if (object instanceof Boolean)
			return (Boolean) object;

		String str = (String) object;
		if (StringUtil.isBlank(str))
			return null;

		return new Boolean(str.equals(Constants.YES.toString()));
	}

	public static boolean isBlank(Object value) {
		if (value == null)
			return true;

		if (value instanceof String) {
			if (StringUtil.isBlank((String) value))
				return true;
		}

		return false;
	}

	public static boolean isNotBlank(Object value) {
		return !isBlank(value);
	}

	public static String replaceRegex(String regex, String orgi, int pos) {
		if (isBlank(orgi) || isBlank(regex))
			return orgi;

		Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(orgi);

		while (m.find()) {
			String outStr = m.group(pos);
			orgi = orgi.replace(m.group(0), outStr);
		}

		return orgi;
	}

	public static String get(String regex, String orgi, int pos) {
		if (isBlank(orgi) || isBlank(regex))
			return null;

		Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(orgi);

		while (m.find()) {
			String outStr = m.group(pos);
			return outStr;
		}

		return null;
	}

	public static Map<String, Object> String2Map(String mapStr) {
		Map<String, Object> map = new HashMap<String, Object>();
		mapStr = mapStr.substring(1, mapStr.length() - 1);
		String[] mapElements = mapStr.split(",");

		for (int i = 0; i < mapElements.length; i++) {
			String[] obj = mapElements[i].split("=");
			if (obj.length == 1) {
				continue;
			}

			String key = obj[0];
			String value = obj[1];
			map.put(key, value);
		}

		return map;
	}

	public static void sql2code() {
		Scanner objScanner = new Scanner(System.in);
		System.out.println("请输入StringBuffer变量的名称：");
		String strBuffer = objScanner.next();
		System.out.println("请输入SQL语句(最后一行需加回车符)：");
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		String s;
		int index = 0;
		try {
			while ((s = br.readLine()).length() != 0) {
				if (index == 0) {
					System.out.println("\n\n您要的代码如下：\n");
				}
				System.out.println(strBuffer + ".append(\" " + s + " \");");
				index++;
			}
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}

	}

	public static boolean in(String[] targets, String value, boolean ignoreCase) {
		if (targets == null)
			return false;

		for (String target : targets) {
			if (ignoreCase) {
				if (value.equalsIgnoreCase(target))
					return true;
			} else {
				if (value.equals(target))
					return true;
			}
		}

		return false;
	}

	public static String compress(String value) {
		if (isBlank(value))
			return value;

		try {
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			GZIPOutputStream gzip = new GZIPOutputStream(out);
			gzip.write(value.getBytes());
			gzip.close();
			return out.toString("ISO-8859-1");
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}

		return null;
	}

	public static String unCompress(String value) {
		if (isBlank(value))
			return value;

		try {
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ByteArrayInputStream in = new ByteArrayInputStream(value.getBytes("ISO-8859-1"));
			GZIPInputStream gunzip = new GZIPInputStream(in);
			byte[] buffer = new byte[256];
			int n;
			while ((n = gunzip.read(buffer)) >= 0) {
				out.write(buffer, 0, n);
			}

			return out.toString("UTF-8");
		} catch (UnsupportedEncodingException e) {
			logger.error(e.getMessage(), e);
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}

		return null;
	}

	/**
	 * 将Object转为xml
	 * 
	 * @param object
	 * @return
	 * 
	 * @author Jay.Wu
	 */
	public static String obj2Xml(Object object) {
		XStream xstream = new XStream();
		return xstream.toXML(object);
	}

	/**
	 * 将xml转为Object
	 * 
	 * @param xml
	 * @return
	 * 
	 * @author Jay.Wu
	 */
	public static Object xml2Obj(String xml) {
		XStream xstream = new XStream();
		return xstream.fromXML(xml);
	}

	/**
	 * 如果为null则返回“”;
	 * 
	 * @param input
	 * @return
	 * 
	 * @author Solex.Li
	 */
	public static String nullToEmpty(Object input) {
		String output;
		if (input == null)
			return "";
		try {
			output = input.toString();
		} catch (Exception e) {
			output = (String) input;
		}
		return output;
	}
}
